package com.lp.mgt.commons.exception;


import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import com.lp.mgt.constants.ExceptionEnums;
 
 
/**
 * @program: 测试
 * @description:全局的异常处理类
 * @author: 
 * @create: 2018-10-19 11:38
 	*1 自定义错误页面:templates下提供一个名为error的页面。所有异常都会统一跳转该页面

	*2 @ExceptionHandle 注解处理异常：该注解修饰的方法写在一个controller中，但只能处理当前ctroller
	
	*3 @ControllerAdvice+@ExceptionHandler 提供一个@ControllerAdvice修饰的全局异常类如本程序。注解处理异常
	
	*4 配置 SimpleMappingExceptionResolver 提供一个返回类型为SimpleMappingExceptionResolver的方法，处理异常
	
	*5 自定义 HandlerExceptionResolver 全局配置类中实现该接口，根据不同类型异常做不同处理
 **/
@ControllerAdvice
public class GlobalExceptionHandler {

	private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	private static final String DEFAULT_ERROR_VIEW="exception";//默认异常页面
	
	
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ModelAndView exceptionHandler(HttpServletRequest request,HttpServletResponse response, Exception e) {
        ModelAndView mv=new ModelAndView();
        logger.info(getClass().getName() + "统一异常处理-后台异常信息：\n >>>>>>:"+e.getMessage());
        //1 获取错误状态码
        //HttpStatus httpStatus=HttpStatus.valueOf((Integer) request.getAttribute("javax.servlet.error.status_code"));
        HttpStatus httpStatus=getStatus(request);
        logger.info(getClass().getName() + "统一异常处理-错误状态码：\n >>>>>>:"+httpStatus);
        //2 返回错误提示
        ExceptionEnums ee=ExceptionEnums.getExamType(String.valueOf(httpStatus.value()));
        //判断是否ajax请求
        String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
    	if(!"XMLHttpRequest".equalsIgnoreCase(header)){
    		//3 将错误信息放入mv中
    		mv.addObject("code", ee.getCode());
    		mv.addObject("msg", ee.getMsg());
    		mv.setViewName("error/"+DEFAULT_ERROR_VIEW);
    		logger.debug(getClass().getName() + "统一异常处理：普通请求。");
    	}else {
    		//ajax请求则重定向返回json的方法
    		mv.setViewName("redirect:/exception/returnException？code="+ee.getCode()+"&msg="+URLEncoder.encode(ee.getMsg()));
    		logger.debug(getClass().getName() + "统一异常处理：AJAX请求。");
    	}
        logger.debug(getClass().getName() + "统一异常处理响应结果：MV="+mv);
        return mv;
    }

    
	/**
	 * 
	 * @描述：获取错误状态码
	 * @创建人：wyait
	 * @创建时间：2018年5月31日 下午2:19:39
	 * @param request
	 * @return
	 */
	private HttpStatus getStatus(HttpServletRequest request) {
		Integer statusCode = (Integer) request
				.getAttribute("javax.servlet.error.status_code");
		if (statusCode == null) {
			return HttpStatus.INTERNAL_SERVER_ERROR;
		}
		try {
			return HttpStatus.valueOf(statusCode);
		}
		catch (Exception ex) {
			return HttpStatus.INTERNAL_SERVER_ERROR;
		}
	}

}